package api;

import com.fasterxml.jackson.databind.ObjectMapper;
import compile.Answer;
import compile.Question;
import compile.Task;
import dao.Problem;
import dao.ProblemDAO;
import util.CodeInValidException;
import util.HttpUtil;
import util.ProblemNotFoundException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/compile")
public class CompileServlet extends HttpServlet {
    static class CompileRequest {
        public int id;
        public String code;
    }
    static class CompileResponse {
        //约定error为0表示运行ok，error为1表示编译出错，error为2表示运行出错，error为3表示其他错误
        public int error;
        public String reason;
        public String stdout;
    }

    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        CompileRequest compileRequest = null;
        CompileResponse compileResponse = new CompileResponse();
        try {
            //1.获取到请求中的正文，并按照json格式进行解析
            String body = HttpUtil.readBody(req);
            compileRequest = objectMapper.readValue(body,CompileRequest.class);

            //2.根据请求中的题目id查询数据库，获取到测试用例代码
            ProblemDAO problemDAO = new ProblemDAO();
            Problem problem = problemDAO.selectOne(compileRequest.id);
            if(problem==null){
                throw new ProblemNotFoundException();
            }
            String testCode = problem.getTestCode();

            //3.再获取到用户提交的代码，并和测试用例代码进行拼接
            String requestCode = compileRequest.code;
            String finalCode = mergeCode(requestCode, testCode);
            if(finalCode==null||"".equals(finalCode)){
                throw new CodeInValidException();
            }

            //4.创建一个Task实例，调用complieAndRun方法来执行
            Task task = new Task();
            Question question = new Question();
            question.setCode(finalCode);
            Answer answer = task.compileAndRun(question);

            //5.把运行结果包装成一个HTTP响应并返回
            compileResponse.error = answer.getError();
            compileResponse.reason = answer.getReason();
            compileResponse.stdout = answer.getStdout();

            String respString = objectMapper.writeValueAsString(compileResponse);
        } catch (ProblemNotFoundException e) {
            compileResponse.error = 3;
            compileResponse.reason = "没有找到题目,题目id=" + compileRequest.id;
        }catch (CodeInValidException e) {
            compileResponse.error = 3;
            compileResponse.reason = "提交的代码不符合规范";
        }catch (InterruptedException e) {
        e.printStackTrace();
        }finally {
            resp.setStatus(200);
            resp.setContentType("application/json; charset=utf-8");
            String respString = objectMapper.writeValueAsString(compileResponse);
            resp.getWriter().write(respString);
        }
    }

    private String mergeCode(String requestCode, String testCode) {
        //1.先从 requestCode 中找到末尾的 } , 并且截取出前面的代码
        int pos = requestCode.lastIndexOf("}");
        if (pos == -1) {
            return null;
        }

        //2.把 testCode 拼接到后面, 并再拼接上一个 } 就好了
        return requestCode.substring(0, pos) + testCode + "}";
    }
}
